package com.xenos.myPoker;

import java.util.ArrayList;
import java.util.Collections;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

/**
 * 不洗牌，随机取牌
 * 
 * @author Administrator
 *
 */
public class GameMainBeta1 {
	private List<Player> playerList;
	private List<Poker> pokerList; // 存放一副卡牌（未洗）
	private int definePlayerNum;
	private int defineHandCardNum;// 每个玩家要抽取的卡牌张数
	Scanner scanner;

	public GameMainBeta1() {
		definePlayerNum = 3;
		defineHandCardNum = 5;
		pokerList = Poker.makePoker();// Poker用静态方法创建是因为Poker是一定的
		playerList = new ArrayList<>();
		scanner = new Scanner(System.in);
	}

	public GameMainBeta1(int definePlayerNum, int defineHandCardNum) {
		this.definePlayerNum = definePlayerNum;
		this.defineHandCardNum = defineHandCardNum;
		pokerList = Poker.makePoker();
		playerList = new ArrayList<>();
		scanner = new Scanner(System.in);
	}

	/**
	 * 创建玩家
	 */
	public void createPlayers() {
		int id;
		String name;
		int playerNum = definePlayerNum;// 循环变量
		int playerIndex = 1;
		List<Integer> idList = new ArrayList<>();// 编号不能重复，利用list的contains方法解决重复问题
		while (playerNum > 0) {
			System.out.println("开始创建第" + playerIndex + "位玩家");
			System.out.println("请输入玩家编号:");
			try {
				id = scanner.nextInt();// 接收控制台输入数据，没有异常则将输入值赋予id
				if (idList.contains(id)) {// 编号不能重复，利用list的contains方法解决重复问题
					System.out.println("编号重复，请重新输入！");
					continue;
				}
				idList.add(id); // 用来存档输入id
			} catch (InputMismatchException e) {// 输入编号的格式异常处理
				System.out.println("非int编号，请重新输入！");
				scanner.next(); // 【吸收缓冲区】不然会死循环
				continue;
			}
			System.out.println("输入玩家姓名:");
			name = scanner.next();
			playerList.add(new Player(id, name)); // 添加玩家从这里可以看出复用性了！先不急于填充域，都获取再填充。
			System.out.println("第" + playerIndex + "位玩家创建成功！");
			playerNum--;
			playerIndex++;
		}
	}

	/**
	 * 洗牌发牌(利用发牌随机)； 要给各自player建造一个私有list存放随机取出的卡牌playerPokerList（Player的构造已给出）；
	 * 从playerList中取出player，调用他的playerPokerList的add方法加入卡牌；
	 */
	public void playerGetPoker() {
		Random random = new Random();
		int playerNum = definePlayerNum;
		int playerIndex = 0;
		int pokerNum = 52;// remove删牌 pokerNum--
		int pokerIndex = 0;// 随机抽到的牌的index

		// 前半部循环为一个player抽一张牌，当抽满两张后给下一个抽
		while (playerNum > 0) {
			// 解决因参数设置不当,导致牌量不足以继续游戏的问题,参数包括人数和牌数,最终影响抽完后的牌数
			try {
				pokerIndex = random.nextInt(pokerNum);
			} catch (IllegalArgumentException e) {
				// random.nextInt的异常，当cardNum<0时捕获
				// 异常要早发现，所以应该在main函数cmd传参时就用if条件语句发现异常，这里没错但时机不好。
				System.out.println("***卡牌已被抽完,游戏无法继续!***\n【提示】：请重新运行游戏并设置合理的参数！");
				System.exit(-1);
			}
			// 利用remove【取出】元素解决抽到重复牌的问题 【E remove(index)】
			playerList.get(playerIndex).getPlayerPokerList().add(pokerList.remove(pokerIndex));
			pokerNum--;

			// 限定为给一个player抽牌，没抽够defineHandCardNum时一直抽
			if (!(playerList.get(playerIndex).getPlayerPokerList().size() == defineHandCardNum)) {
				continue;
			}

			// 为一个player抽完牌后前进为下一个抽
			playerNum--;
			playerIndex++;
		}
	}

	/**
	 * 在执行playerGetPoker()后得到一个包含两张牌的ArrayList(包含洗牌和发牌逻辑)
	 * 每人两张牌先自己比较，每人的最大牌再比较(由sort排升序，然后取最大或最小值)
	 * 
	 * 【此算法时间复杂度高于GameMainBeta2中的gameCompare 】
	 */
	public void gameCompare() {
		// 自己的牌先自己比较;
		// 【算法】：sort升序ArrayList，取末尾的值为最大值。
		for (int i = 0; i < definePlayerNum; i++) {
			Collections.sort(playerList.get(i).getPlayerPokerList());
			System.out.println("玩家 " + playerList.get(i).getName() + " 最大的卡牌为： "
					+ playerList.get(i).getPlayerPokerList().get(defineHandCardNum - 1));
		}

		// 【这实际上就是个max方法】，用工具类【Collections.max】更简洁。
		// 初始时最大牌bigPokerCard和赢家winnerName指向第一个玩家
		int compare;
		Poker bigPokerCard = playerList.get(0).getPlayerPokerList().get(defineHandCardNum - 1);
		String winnerName = playerList.get(0).getName();
		for (int j = 0; j < definePlayerNum - 1; j++) {
			compare = bigPokerCard.compareTo(playerList.get(j + 1).getPlayerPokerList().get(defineHandCardNum - 1));
			if (compare > 0) {
				// 当前比下一个大时，不改变bigPokerCard和winnnerName的指向
				System.out.println("-------玩家 " + winnerName + " 第" + (j + 1) + "轮获胜-------");
			} else {
				// 下一个比当前大时，bigPokerCard和winnerName指向下一个玩家
				winnerName = playerList.get(j + 1).getName();
				bigPokerCard = playerList.get(j + 1).getPlayerPokerList().get(defineHandCardNum - 1);

				System.out.println("-------玩家 " + winnerName + " 第" + (j + 1) + "轮获胜-------");
			}
		}
		System.out.println("~~~~~~~！恭喜玩家 " + winnerName + "获胜！~~~~~~~");
	}

	/**
	 * 打印玩家占有的手牌
	 */
	public void printPlayerPoker() {
		for (int j = 0; j < definePlayerNum; j++) {
			System.out.println(
					"玩家 " + playerList.get(j).getName() + " 有以下卡牌:  " + playerList.get(j).getPlayerPokerList());
		}
	}

	/**
	 * 复用：1.增加游戏玩家;2.增加持有牌数；
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("-------------创建扑克牌-------------");
		GameMainBeta1 gameMainBeta1;
		if (args.length == 0) {
			gameMainBeta1 = new GameMainBeta1();
		} else if (args.length == 2) {
			// 参数设置异常处理，人数大于1小于等于52，取牌数大于0小于等于26,抽到的总牌数不超过52
			if ((Integer.parseInt(args[0]) <= 1) || (Integer.parseInt(args[0]) > 52) || (Integer.parseInt(args[1]) < 1)
					|| (Integer.parseInt(args[1]) > 26)
					|| (Integer.parseInt(args[0]) * Integer.parseInt(args[1]) > 52)) {
				System.out.println("*****参数设置错误，请重新设置玩家数或取牌数*****");
				return;
			}
			gameMainBeta1 = new GameMainBeta1(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
		} else {
			System.out.println("Usuage: Java GameMain [definePlayerNum] [defineHandCardNum]");
			return;
		}
		System.out.println("-------------创建玩家------------");
		gameMainBeta1.createPlayers();
		System.out.println("------------玩家随机抽牌----------");
		gameMainBeta1.playerGetPoker();
		System.out.println("--------------比较大小------------");
		gameMainBeta1.gameCompare();
		System.out.println("--------玩家各自的手牌为--------");
		gameMainBeta1.printPlayerPoker();
	}
}
